/*-------------------------------------------------------------------------------------------------*/
/*                                                                                                 */
/*                                                                                                 */
/* Copyright (c) 2008 Nuvoton Corp. Corporation                                                    */
/* All rights reserved                                                                             */
/*                                                                                                 */
/*-------------------------------------------------------------------------------------------------*/
/* File Name:                                                                                      */
/*     udp.c                                                                                       */
/* Description:                                                                                    */
/*     This application tests lwip UDP related functions. It keeps send UDP packet and             */
/*          receive UDP packets at the same time                                                   */
/* History:                                                                                        */
/*                                                                                                 */
/* Project:                                                                                        */
/*-------------------------------------------------------------------------------------------------*/

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#include "wblib.h"
#include "NUC900_lwip.h"



INT _count = 0;

/* Receive the packet from ethernet, do nothing and drop it */
static VOID _MyRecv(VOID *arg, struct udp_pcb *pcb, struct pbuf *p, struct ip_addr *addr, u16_t port)
{

    _count++;
    pbuf_free(p);
    return;

}

static VOID _InitSystem(VOID)
{

    WB_PLL_T sysClock;

    sysDisableCache();
    sysInvalidCache();
    sysSetMMUMappingMethod(MMU_DIRECT_MAPPING);
    sysEnableCache(CACHE_WRITE_BACK);

    sysClock.pll0 = PLL_166MHZ;
    sysClock.pll1 = PLL_100MHZ;
    sysClock.cpu_src = CPU_FROM_PLL0;
    sysClock.ahb_clk = AHB_CPUCLK_1_2;
    sysClock.apb_clk = APB_AHB_1_2;

    sysSetPLLConfig(&sysClock);

}


INT main(VOID)
{

    struct ip_addr gw, ipaddr, netmask;
    struct ip_addr sb;
    struct netif netif;
    struct udp_pcb *rx_pcb, *tx_pcb;
    struct pbuf *tmp_buf;
    UINT8 payload[1400];
    INT i;


    _InitSystem();

    IP4_ADDR(&gw, 192, 168, 0, 1);
    IP4_ADDR(&ipaddr, 192, 168, 0, 228);
    IP4_ADDR(&netmask, 255, 255, 255, 0);

    IP4_ADDR(&sb, 192, 168, 0, 249);
    for (i = 0; i < sizeof(payload); i++)
        payload[i] = 0x55;


    stats_init();
    sys_init();

    /*  mem_init(); */ /* This function does nothing */
    memp_init();
    pbuf_init();



    etharp_init();

    ip_init();
    udp_init();
    tcp_init();


    netif_add(&netif, &ipaddr, &netmask, &gw, NULL, ethernetif_init, ip_input);
    netif_set_default(&netif);
    netif_set_up(&netif);

    /* This is the pcb for Rx */
    rx_pcb = udp_new();
    if (udp_bind(rx_pcb,IP_ADDR_ANY,999) != ERR_OK)
        sysprintf("bind error\n");


    udp_recv(rx_pcb, _MyRecv, NULL);

    /* This is the pcb for Tx */
    tx_pcb = udp_new();

    /* Keep sending packets to ethernet */
    while (1) {
        tmp_buf = pbuf_alloc(PBUF_TRANSPORT, sizeof(payload), PBUF_RAM);
        memcpy(tmp_buf->payload, payload, i);
        udp_sendto(tx_pcb, tmp_buf, &sb, 999);
        pbuf_free(tmp_buf);

    }

    while (1);

}